﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
    class Statistics
    {

        public static double getExpectation(double[] A)
        {
            double Result = 0;
            foreach (double a in A)
            {
                Result += a;
            }
            return Result / A.Length;
        }


        public static double getDispersion(double[] A)
        {
            double Result = 0;
            double exp = getExpectation(A);
            foreach (double a in A)
            {
                Result += (exp - a) * (exp - a);
            }
            return Result / A.Length;
        }

        public static double getGaussFractile(double q)
        {
            double a = 1 - q;
            double t = Math.Sqrt(Math.Log(1.0 / (a * a)));
            double c0=2.515517,c1= 0.8028538,c2= 0.01032;
            double d1 = 1.432788, d2 = 0.189269, d3 = 0.001308;
            return t - (c0 + c1 * t + c2 * t * t) / (1 + d1 * t + d2 * t * t + d3 * t * t * t);
        }


        public static double getStudentFractile(double v, double q)
        {
            double lambda = getGaussFractile(q);
            double q1 = (lambda * lambda + 1) * lambda / 4;
            double q2 = ((5 * lambda * lambda + 16) * lambda * lambda + 3) * lambda/96;
            double q3 = (((3 * lambda * lambda * lambda + 19) * lambda * lambda + 17) * lambda * lambda - 15) * lambda / 384;
            double q4 = ((((79 * lambda * lambda + 776) * lambda * lambda + 1482) * lambda * lambda - 1920) * lambda * lambda - 945) * lambda / 92160;
            return lambda + q1 / v + q2 / v / v + q3 / v / v / v + q4 / v / v / v / v;
        }

        public static void getErrorsMethod1(double []A,bool []Error,double []U,double alpha)
        {
            double exp=getExpectation(A);
            double sigma=Math.Sqrt(getDispersion(A));
            double fract=getStudentFractile(A.Length-1,1-alpha);
           // MessageBox.Show(fract.ToString());
          //  fract=Math.Abs(fract);
            for(int i=0;i<A.Length;i++)
            {
                double u=(A[i]-exp)/sigma;
                u=Math.Abs(u);
                U[i] = u;
                if(u>fract)Error[i]=true;else Error[i]=false;

            }
        }
        private static double [] ArrayWithoutElem(double[] A, int el)
        {
            double[] B = new double[A.Length - 1];
            int idx = 0;
            for (int i = 0; i < A.Length; i++)
            {
                if (i == el) continue;
                B[idx++] = A[i];
            }
            return B;
        }
        public static void getErrorsMethod2(double[] A, bool[] Error, double[] U, double alpha)
        {
                
    
            
           
            double fract = getStudentFractile(A.Length - 1, 1 - alpha);
            // MessageBox.Show(fract.ToString());
            //  fract=Math.Abs(fract);
            for (int i = 0; i < A.Length; i++)
            {
                double []B = ArrayWithoutElem(A, i);
                double exp = getExpectation(B);
                double sigma = Math.Sqrt(getDispersion(B));
                double u = (A[i] - exp) / sigma;
                u = Math.Abs(u);
                U[i] = u;
                Error[i] = (u > 4);

            }
        }

    
    }
}
